package com.siyuanren.gcocp.service.impl;


import com.siyuanren.gcocp.base.BaseObject;
import com.siyuanren.gcocp.dto.*;
import com.siyuanren.gcocp.dto.wx.WxUserInviteCourseDTO;
import com.siyuanren.gcocp.entity.*;
import com.siyuanren.gcocp.enumm.CourseTeachType;
import com.siyuanren.gcocp.enums.StudyStatusEnum;
import com.siyuanren.gcocp.mapper.MyWxActiveMapper;
import com.siyuanren.gcocp.mapper.MyWxCourseMapper;
import com.siyuanren.gcocp.mapper.MyWxUserVoucherMapper;
import com.siyuanren.gcocp.mapper.base.*;
import com.siyuanren.gcocp.service.*;
import com.siyuanren.gcocp.util.DateUtil;
import com.siyuanren.gcocp.util.ObjectUtil;
import com.siyuanren.gcocp.util.QrCodeCreateUtil;
import com.siyuanren.gcocp.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * @author PVer
 */
@Slf4j
@Service
public class CourseServiceImpl extends BaseObject implements CourseService {

    @Autowired
    private MyWxCourseMapper courseMapper;
    @Autowired
    WxUserCourseMapper userCourseMapper;
    @Autowired
    private WxDictMapper dictMapper;
    @Autowired
    private WxBannerMapper bannerMapper;
    @Autowired
    private WxGroupQrcodeMapper groupQrcodeMapper;
    @Autowired
    private WxCourseLiveMapper courseLiveMapper;
    @Autowired
    private WxCourseStartService courseStartService;
    @Autowired
    private CourseStatisticsService courseStatisticsService;
    @Autowired
    private WxCourseStartMapper courseStartMapper;
    @Autowired
    private UserVoucherService userVoucherService;
    @Autowired
    private MyWxUserVoucherMapper userVoucherMapper;
    @Autowired
    private MyWxActiveMapper activeMapper;
    @Autowired
    private WxVoucherMapper voucherMapper;

    @Override
    public WxCourseTeaDTO getById(int id) {
        return courseMapper.getById(id);
    }

    /**
     * 返回推荐课程
     * @return
     * @throws Exception
     */
    public List<WxCategoryDTO> getRecommendCourses(Integer userId) throws Exception {
        List<WxCategoryDTO> recommendCourses = courseMapper.getRecommendCourses(userId);

        Iterator<WxCategoryDTO> iteratorCate = recommendCourses.iterator();
        while (iteratorCate.hasNext()) {
            WxCategoryDTO recommendCours = iteratorCate.next();
            Iterator<WxCourseDTO> iteratorCourse = recommendCours.getCourses().iterator();
            int maxSize = 0;
            while (iteratorCourse.hasNext()) {
                WxCourseDTO wxCourseDTO = iteratorCourse.next();
                // 首页最多显示四个课程
                if (maxSize++ > 4) {
                    iteratorCourse.remove();
                } else {
                    initCourseDTO(userId, wxCourseDTO);
                }
            }
        }
        return recommendCourses;
    }

    /**
     * 返回课程订购数量
     * @param courseId
     * @return
     */
    private int getOrderCount(Integer courseId) {
        WxCourse course = courseMapper.selectByPrimaryKey(courseId);
        WxUserCourseExample countExam = new WxUserCourseExample();
        countExam.or().andCourseIdEqualTo(courseId);
        return (int) userCourseMapper.countByExample(countExam) + course.getInitOrderCount();
    }

    @Override
    public WxUserCourseListDTO getUserCourseList(QueryUserCourseVO courseVO) throws Exception {
        WxUserCourseListDTO userCourseListDTO = new WxUserCourseListDTO();
        List<WxCourseDTO> userCourseDAOList = courseMapper.getUserCourseList(courseVO);
        for (WxCourseDTO wxCourseDTO : userCourseDAOList) {
            initCourseDTO(courseVO.getUserId(), wxCourseDTO);
        }
        userCourseListDTO.setCourses(userCourseDAOList);
        return userCourseListDTO;
    }

    /**
     * 初始化课程列表的课程内容
     * @param userId
     * @param courseDTO
     */
    private void initCourseDTO(Integer userId, WxCourseDTO courseDTO) throws Exception {
        WxUserCourseExample example = new WxUserCourseExample();
        example.or().andUserIdEqualTo(userId).andCourseIdEqualTo(courseDTO.getCourseId());
        List<WxUserCourse> myCourseList = userCourseMapper.selectByExample(example);


        // 订购数量
        courseDTO.setOrderCount(getOrderCount(courseDTO.getCourseId()));
        // 是否购买
        if (myCourseList.size() > 0) {
            // 已经购买, 设置购买日期
            courseDTO.setPayState(1);
            courseDTO.setCourseStartId(myCourseList.get(0).getCourseStartId());
            WxCourseStart start = courseStartMapper.selectByPrimaryKey(courseDTO.getCourseStartId());
            if (start != null) {
                courseDTO.setCourseNumber(start.getCourseNumber());
                courseDTO.setRegisterLastTime(start.getRegisterLastTime());
                courseDTO.setCheckInTime(start.getCheckInTime());
                courseDTO.setStartTime(start.getStartTime());
            }
        } else {
            // 没有购买, 寻找最近开课期数
            WxCourseStart start = courseStartService.getLatestStart(courseDTO.getCourseId());
            if (start != null) {
                courseDTO.setCourseStartId(start.getId());
                courseDTO.setCourseNumber(start.getCourseNumber());
                courseDTO.setRegisterLastTime(start.getRegisterLastTime());
                courseDTO.setCheckInTime(start.getCheckInTime());
                courseDTO.setStartTime(start.getStartTime());
            }
        }
        // 学习状态
        initStudyStatus(courseDTO);
    }

    /**
     * 初始化课程的学习状态
     * @param wxCourseDTO
     */
    private void initStudyStatus(WxCourseDTO wxCourseDTO) {
        if (wxCourseDTO.getCourseStartId() <= 0
                || wxCourseDTO.getCheckInTime()==null
                || wxCourseDTO.getStartTime()==null) {
            wxCourseDTO.setStudyStatus(StudyStatusEnum.STUDY_STUDING.getStatus());
            wxCourseDTO.setStudyStatusStr(StudyStatusEnum.STUDY_STUDING.getDesc());
            return;
        }
        Date gradDate = DateUtil.getDateAfter(wxCourseDTO.getStartTime(), wxCourseDTO.getChapterCount());
        wxCourseDTO.setGradTime(gradDate);

        if (wxCourseDTO.getTeachType() == CourseTeachType.FreeTeach.getValue()) {
            wxCourseDTO.setStudyStatus(StudyStatusEnum.STUDY_STUDING.getStatus());
            wxCourseDTO.setStudyStatusStr(StudyStatusEnum.STUDY_STUDING.getDesc());
        } else {
            if (new Date().after(gradDate)) {
                wxCourseDTO.setStudyStatus(StudyStatusEnum.STUDY_COMPLETE.getStatus());
                wxCourseDTO.setStudyStatusStr(StudyStatusEnum.STUDY_COMPLETE.getDesc());
            } else if (wxCourseDTO.getStartTime() != null && new Date().after(wxCourseDTO.getStartTime())) {
                wxCourseDTO.setStudyStatus(StudyStatusEnum.STUDY_STUDING.getStatus());
                wxCourseDTO.setStudyStatusStr(StudyStatusEnum.STUDY_STUDING.getDesc());
            } else if (wxCourseDTO.getCheckInTime() != null && new Date().after(wxCourseDTO.getCheckInTime())) {
                wxCourseDTO.setStudyStatus(StudyStatusEnum.STUDY_START.getStatus());
                wxCourseDTO.setStudyStatusStr(StudyStatusEnum.STUDY_START.getDesc());
            } else {
                wxCourseDTO.setStudyStatus(StudyStatusEnum.STUDY_WAIT.getStatus());
                wxCourseDTO.setStudyStatusStr(StudyStatusEnum.STUDY_WAIT.getDesc());
            }
        }
    }

    @Override
    public List<WxUserInviteCourseDTO> getUserInviteCourseList(Integer userId) throws Exception {
        List<WxUserInviteCourseDTO> list = courseMapper.getUserInviteCourseList(userId);
        for (WxUserInviteCourseDTO dto : list) {
            WxVoucher voucher = voucherMapper.selectByPrimaryKey(dto.getInviteVoucherId());
            if (voucher != null) {
                String qrcodeUrl = QrCodeCreateUtil.genVoucherQRcode(userId, voucher.getCourseId(), voucher.getId());
                dto.setInviteFriendQrcodeUrl(qrcodeUrl);
            }
        }
        return list;
    }

    @Override
    @Transactional
    public void submitCourseProgress(WxUserCourse userCourse) {
        WxUserCourseExample example = new WxUserCourseExample();
        example.or().andUserIdEqualTo(userCourse.getUserId()).andCourseIdEqualTo(userCourse.getCourseId());
        userCourseMapper.updateByExampleSelective(userCourse, example);
    }

    @Override
    public CourseGradDTO getCourseGrad(QueryGradVO queryGradVO) throws Exception {
        return courseMapper.getCourseGrad(queryGradVO);
    }

    @Override
    public List<WxBannerDTO> getBanners(Integer userId) {
        WxBannerExample example = new WxBannerExample();
        example.or().andAvailableEqualTo(true);
        example.setOrderByClause("sort desc");
        List<WxBanner> banners = bannerMapper.selectByExample(example);
        List<WxBannerDTO> dtos = new ArrayList<>();
        for (WxBanner banner : banners) {
            WxBannerDTO d = new WxBannerDTO();
            BeanUtils.copyProperties(banner, d);
            dtos.add(d);

        }
        return dtos;
    }

    @Override
    public List<WxCourseLive> getHomeLives(Integer userId) {
        WxCourseLiveExample example = new WxCourseLiveExample();
        example.or().andEndtimeGreaterThan(new Date(new java.util.Date().getTime()))
                .andAvailableEqualTo(true);
        example.setOrderByClause("sort desc");
        List<WxCourseLive> courseLives = courseLiveMapper.selectByExample(example);
        for (WxCourseLive courseLive : courseLives) {
            courseLive.setImg(courseLive.getImg());
        }
        return courseLives;
    }

    @Override
    public WxCourse getByActive(Integer activeId) {
        return courseMapper.getActiveFollowCourse(activeId);
    }

    @Override
    public WxCourse getSponsorCourseByActive(Integer activeId) {
        return courseMapper.getActiveSponsorCourse(activeId);
    }

    @Override
    public WxGroupQrcodeDTO getWxGroupQrcode(QueryWxGroupVO queryWxGroup) throws Exception {
        List<WxGroupQrcodeDTO> list = courseMapper.getWxGroupQrcode(queryWxGroup);
        if (list.isEmpty()) {
            return null;
        } else {
            return list.get(0);
        }
    }

    @Override
    public CourseDetailDTO getCourseDetail(QueryCourseDetailVO queryDetailVO) throws Exception {
        CourseDetailDTO detailDTO = courseMapper.getCourseDetail(queryDetailVO);
        // 查询优惠券
        if (ObjectUtil.isEmpty(queryDetailVO.getVoucherId())) {
            QueryVoucherVO vo = new QueryVoucherVO();
            vo.setCourseId(queryDetailVO.getCourseId());
            vo.setUserId(queryDetailVO.getUserId());
            List<WxUserVoucher> voucherForCourse = userVoucherService.getVoucherForCourse(vo);
            if (voucherForCourse.size() > 0) {
                detailDTO.setVoucher_fee(voucherForCourse.get(0).getVoucherFee());
            }
        } else {
            // 指定使用优惠券
            WxUserVoucher userVoucher = userVoucherMapper.selectByPrimaryKey(queryDetailVO.getVoucherId());
            if (userVoucher != null) {
                detailDTO.setVoucher_fee(userVoucher.getVoucherFee());
            }
        }
        // 设置订购数量
        detailDTO.setOrderCount(getOrderCount(queryDetailVO.getCourseId()));
        // 查询是否已购买
        WxUserCourseExample exmaple = new WxUserCourseExample();
        exmaple.or().andUserIdEqualTo(queryDetailVO.getUserId())
                .andCourseIdEqualTo(queryDetailVO.getCourseId())
                .andAvailableEqualTo(true);
        List<WxUserCourse> userCourseList = userCourseMapper.selectByExample(exmaple);
        WxCourseStart courseStart = null;
        if (userCourseList.size() > 0) {
            detailDTO.setPayState(1);
            courseStart = courseStartMapper.selectByPrimaryKey(userCourseList.get(0).getCourseStartId());
        } else {
            // 查询课程期数
            courseStart = courseStartService.getLatestStart(queryDetailVO.getCourseId());
        }
        if (courseStart != null) {
            detailDTO.setCourseNumber(courseStart.getCourseNumber());
            detailDTO.setRegisterLastTime(courseStart.getRegisterLastTime());
            detailDTO.setStartTime(courseStart.getStartTime());
        }

        // 设置加群二维码
        QueryWxGroupVO vo = new QueryWxGroupVO();
        vo.setUserId(queryDetailVO.getUserId());
        vo.setCourseId(queryDetailVO.getCourseId());
        List<WxGroupQrcodeDTO> list = courseMapper.getWxGroupQrcode(vo);
        if (list.size() > 0) {
            detailDTO.setGroupQrcodeImg(list.get(0).getQrcodeImg());
        }

        // 判断是否有活动正在进行中
        if (!ObjectUtil.isEmpty(detailDTO.getActiveId())) {
            WxActiveExample exma = new WxActiveExample();
            Date now = new Date();
            exma.or().andIdEqualTo(detailDTO.getActiveId())
                    .andAvailableEqualTo(true)
                    .andActiveStartDateLessThanOrEqualTo(now)
                    .andActiveEndDateGreaterThan(DateUtil.getDateBefore(now, 1));
            List<WxActive> wxActives = activeMapper.selectByExample(exma);
            // 如果当前没有正在进行的活动.清空activeId
            if (wxActives.isEmpty()) {
                detailDTO.setActiveId(0);
            }
        }

        return detailDTO;
    }

    @Override
    public List<WxCourseDTO> getCourseByCategory(QueryCourseByCategoryVO vo) throws Exception {
        List<WxCourseDTO> courses = courseMapper.getCourseByCategory(vo);
        Iterator<WxCourseDTO> iteratorCourse = courses.iterator();
        while (iteratorCourse.hasNext()) {
            WxCourseDTO wxCourseDTO = iteratorCourse.next();
            initCourseDTO(vo.getUserId(), wxCourseDTO);
        }
        return courses;
    }

    public static void main(String[]args) {
        CourseServiceImpl courseService = new CourseServiceImpl();
    }
}
